package com.jkm.service.impl;

import com.jkm.dto.UserInsertDTO;
import com.jkm.dto.UserUpdateDTO;
import com.jkm.log.Log;
import com.jkm.mapper.write.WriteUserMapper;
import com.jkm.model.User;
import com.jkm.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.*;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * Created by 四声草 on 2018/4/10.
 */
@RestController
@Log("用户实现类")
/** 所有的@Cacheable（）里面都有一个value＝“xxx”的属性，这显然如果方法多了，写起来也是挺累的，如果可以一次性声明完 那就省事了，
 所以，有了@CacheConfig这个配置，@CacheConfig is a class-level annotation that allows to share the cache names，
 如果你在你的方法写别的名字，那么依然以方法的名字为准。*/
@CacheConfig(cacheNames = "user-service")
public class UserServiceImpl implements UserService {

    @Autowired
    private WriteUserMapper writeUserMapper;

    @Override
    @Transactional
    @Log("保存用户")
    @Caching(evict = {
            @CacheEvict(key = "'selectAll'",allEntries = true)
            /** 表示在执行完方法后清空list列表缓存*/
    })
    public int save(UserInsertDTO userInsertDTO) {
        User user = new User();
        user.setAge(userInsertDTO.getAge());
        user.setName(userInsertDTO.getName());
        int save = writeUserMapper.save(user);
        return save;
    }

    @Override
    @Log("根据用户id获取用户信息")
    /**   @Cacheable(value=”accountCache”)，这个注释的意思是，当调用这个方法的时候，会从一个名叫 accountCache 的缓存中查询，如果没有，
    则执行实际的方法（即查询数据库），并将执行的结果存入缓存中，否则返回缓存中的对象。
    这里的缓存中的 key 就是参数 userName，value 就是 Account 对象。“accountCache”缓存是在 spring*.xml 中定义的名称。*/
    @Cacheable(key = "'selectById-'+#id")
    public User selectById(Long id) {
        System.out.println("调用service实现方法连接数据库");
        return writeUserMapper.selectById(id);
    }

    @Override
    @Log("获取所有用户信息")
    @Cacheable(value = "user-xxx",key = "'selectAll'")
    public List<User> selectAll() {
//        PageHelper.startPage(1, 10);
        List<User> users = writeUserMapper.selectAll();
//        PageInfo<User> pageInfo = new PageInfo<>(users);
        System.out.println("================连接数据库获取用户列表========================");
        return users;
    }

    @Override
    @Log("删除用户")
    @Transactional
    @Caching(evict = {
            @CacheEvict(key = "'selectAll'",allEntries = true)
            /** 表示在执行完方法后清空list列表缓存*/
    })
    /** @CachEvict 的作用 主要针对方法配置，能够根据一定的条件对缓存进行清空*/
    @CacheEvict(key = "'deleteById'+#id")
    public void del(Long id) {
        writeUserMapper.deleteUser(id);
    }

    @Log("更新用户")
    @Override
    @Transactional
    @Caching(evict = {
            @CacheEvict(key = "'selectAll'",allEntries = true)
            /** 表示在执行完方法后清空list列表缓存*/
    })
    /** @CachePut 的作用 主要针对方法配置，能够根据方法的请求参数对其结果进行缓存，和 @Cacheable 不同的是，它每次都会触发真实方法的调用*/
    @CachePut(key = "'updateUser'+#userUpdateDTO.id")
    public int updateUser(UserUpdateDTO userUpdateDTO) {
        User user = writeUserMapper.selectById(userUpdateDTO.getId());
        user.setName(userUpdateDTO.getName());
        user.setAge(userUpdateDTO.getAge());
        int i = writeUserMapper.updateUser(user);
        return i;
    }
}
